-- UIDungeonShop
-- Create by luohj Jan/6/2015
-- 商店界面

require "game/ui/form/hero/HeroUtil"
require "game/ui/form/shop/UIDungeonGoods"
require "game/ui/form/shop/UIDungeonGoodsEquip"

-- UIDungeonShop继承自Layer
UIDungeonShop = class("UIDungeonShop", function()
    return cc.Layer:create();
end);

function UIDungeonShop.create(pos, shopType)
    return UIDungeonShop.new(pos, shopType);
end

-- 商品格最大行数和列数
local MAX_GRID_ROW    = 2;
local MIN_GRID_COLUMN = 3;

-- 内部函数声明
local onGoodsClick;

-- 构造函数
function UIDungeonShop:ctor(pos, shopType)
    -- 初始化
    self:setName("UIDungeonShop");
    local node = cc.CSLoader:createNode("layout/shop/DungeonShop.csb");
    self:addChild(node);
    self.node = node;
    self.shopType = shopType;

    self:setLocalZOrder(UIMgr.TOP_MENU_ZORDER + 1);

    local CT = node:getChildByName("CT");
    local scrollview = findChildByName(CT, "template/scroll_view");
    self.CT = CT;
    scrollview:setVisible(true);
    self.scrollView = scrollview;

    local mask3 = findChildByName(self.CT, "template/mask3");
    mask3:setVisible(true);

    local mask3 = findChildByName(self.CT, "template/mask4");
    mask3:setVisible(true);

    -- 修改滚动方向
    -- 1 垂直
    -- 2 水平
    self.scrollView:setDirection(2);

    -- 记录地牢格子坐标和商店类型
    self.pos      = pos;
    self.shopType = shopType;

    -- 注册事件处理回调函数
    self:registerEventCallback();

    -- 注册点击事件
    self:registerTouchEvent();

    -- 初始化商品格子
    self:initGoodsGrids(self.node);

    -- 重绘
    self:redraw();

    -- 适配
    self:resize();
end

-- 适配
function UIDungeonShop:resize()
    local node = self.node;

    -- bg居中显示并充满整个屏幕
    AlignM.fitToScreen(node, "bg");

    -- CT居中并缩放至合适大小
    AlignM.alignToCenter(node, "CT");

    -- BT置于底部并缩放至合适大小
    AlignM.alignToBottomCenter(node, "BT");
end

-- 获取底部菜单高度Y
function UIDungeonShop:getBottomMenuHeightY()
    local h = cc.Director:getInstance():getOpenGLView():getFrameSize().height;
    return 86 * h / DESIGN_HEIGHT;
end

-- 获取底部菜单高度
function UIDungeonShop:getBottomMenuHeight()
    local w = cc.Director:getInstance():getOpenGLView():getFrameSize().width;
    return 86 * w / DESIGN_WIDTH;
end

-- 计算总列数
function UIDungeonShop:getColNum(num)
    if num <= 3 then
        return num;
    elseif num > 3 and num < 6 then
        return 3;
    else
        return math.ceil(num / MAX_GRID_ROW);
    end
end

-- 初始化商品格
function UIDungeonShop:initGoodsGrids(node)
    local w = DESIGN_WIDTH;
    local h = DESIGN_HEIGHT;

    -- 图标间距(横向)
    local wGap = 23;

    -- 图标间距(纵向)
    local hGap = 33;

    -- 图标宽度
    local iconWidth = 128;

    -- 图片高度
    local iconHeight = 163;

    local topHGap  = 80;
    local leftWGap = 20;

    -- 收集商品信息
    local goodsList = self:gatherGoodsInfo();

    -- 商品的共个数
    local shopCount = #goodsList;
    if shopCount > 6 then
        leftWGap = 15;
    end

    self.scrollView.rows = {};
    self.scrollView:removeAllChildren();
    local itemNode = cc.CSLoader:createNode("layout/shop/GoodsIcon.csb");
    -- @param windowNode    界面节点
    -- @param scrollNode    容器节点
    -- @param itemNode      单元格的节点
    -- @param totalNum      单元格总数
    -- @param maxRowNum     最大行数
    -- @param pageColNum    单页可以显示下的列数
    -- @param wGap          单元格间距(横向) 这里作为最小值使用
    -- @param hGap          单元格间距(纵向)
    -- @param iconWidth     单元格宽度
    -- @param iconHeight    单元格高度
    -- @param topHGap       上方留
    -- @param leftWGap      左右留白  这里作为最小值使用
    -- @param touchEvent    点击事件注册函数
    initScrollGridsHorizontal(self, self.scrollView, itemNode, shopCount, MAX_GRID_ROW, MIN_GRID_COLUMN, wGap, hGap, iconWidth, iconHeight, topHGap, leftWGap, self.registerItemTouchEvent);
end

-- 清空所有的商品格
function UIDungeonShop:clearAllGrid()

end

-- 显示商店
function UIDungeonShop:redraw()
    -- 显示标题
    local titleLabel = findChildByName(self.CT, "template/title");
    local titleStr = DungeonShopM.queryShopRule(self.shopType, "name");
    TextStyleM.setTitleStyle(titleLabel);
    titleLabel:setString(getLocStr(titleStr));

    local subheadLabel = findChildByName(self.CT, "template/subhead");
    TextStyleM.setSubheadStyle(subheadLabel);
    local subheadStr = DungeonShopM.queryShopRule(self.shopType, "tip");
    if subheadStr == "" or type(subheadStr) ~= 'string' then
        subheadStr = getLocStr("choose_goods");
    end
    subheadLabel:setString(subheadStr);

    -- 显示拥有的探索点数量
    local spAmountLabel = findChildByName(self.node, "BT/sp_amount");
    spAmountLabel:setString(ME.user:queryAttrib("search_point"));

    -- 收集商品信息
    local goodsList = self:gatherGoodsInfo();

    -- 格子总数
    local totalGridCount = #goodsList;

    if not goodsList or #goodsList == 0 then
        cclog("收集商品信息失败。");
        return;
    end

    -- 是否因此背景框
    local isHideFrame = DungeonShopM.queryShopRule(self.shopType, "hide_frame");

    -- 显示商品信息
    local totalGoodsCount = #goodsList;
    for i = 1, totalGridCount do
        local grid          = self.scrollView:getChildByName("item" .. i);
        local goodsBg       = grid:getChildByName("bg");
        local iconImg       = grid:getChildByName("goods_icon");
        local moneyImg      = grid:getChildByName("money_icon");
        local moneyLabel    = grid:getChildByName("money_count");
        local soldOutLabel  = grid:getChildByName("sold_out");
        local rankNode      = grid:getChildByName("star_node");
        if not rankNode.initY then
            rankNode.initY = rankNode:getPositionY();
        end

        local countLabel    = grid:getChildByName("item_count");

        if i <= totalGoodsCount then
            grid:setVisible(true);

            local goodsIndex = goodsList[i][1]    -- 商品序号
            local goodsId    = goodsList[i][2];   -- 商品id
            local goodsIcon  = goodsList[i][3];   -- 商品图标
            local payAttrib  = goodsList[i][4];   -- 支付属性
            local goodsPrice = goodsList[i][5];   -- 商品价格
            local goodsCount = goodsList[i][6];   -- 商品数量
            local itemName   = goodsList[i][7];   -- 物品名称
            local itemDesc   = goodsList[i][8];   -- 物品描述
            local soldOut    = goodsList[i][9];   -- 是否售完
            local rank       = goodsList[i][10];  -- 阶位

            -- 为商品图标绑定信息
            iconImg.goodsIndex = goodsIndex;
            iconImg.goodsId    = goodsId;
            iconImg.goodsIcon  = goodsIcon;
            iconImg.payAttrib  = payAttrib;
            iconImg.goodsPrice = goodsPrice;
            iconImg.goodsCount = goodsCount;
            iconImg.itemName   = itemName;
            iconImg.itemDesc   = itemDesc;
            iconImg.soldOut    = soldOut;
            iconImg.rank       = rank;

            if isHideFrame == 1 then
                -- 隐藏商品背景框
                goodsBg:setVisible(false);

                -- 星星显示位置需上移
                local starPosY = rankNode.initY;
                rankNode:setPositionY(starPosY + 3);
            else
                goodsBg:setVisible(true);
            end

            -- 显示商品阶位
            local layer = createStarLayer(rank, "images/ui/symbol/star_little.png", "center", -0.7);
            if layer then
                rankNode:removeAllChildren();
                rankNode:addChild(layer);
            end

            -- 显示商品名称和数量
            TextStyleM.setTextStyle(countLabel, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
            if goodsCount > 1 then
                -- 需要显示数量
                countLabel:setString(tostring(goodsCount));
                countLabel:setVisible(true);
            else
                countLabel:setVisible(false);
            end

            countLabel:setFontSize(24);

            -- 显示商品图标
            iconImg:loadTexture(getItemIconPath(goodsIcon));

            -- 显示价格
            local iconPath;
            local enough = false;

            if type(payAttrib) == "number" then
                -- 道具
                iconPath = getItemIconPath(ItemM.query(payAttrib, "icon"));
                moneyImg:setScale(0.6);
                enough = ItemM.getAmount(ME.user, payAttrib) >= goodsPrice;
            else
                -- 属性
                if payAttrib == "search_point" then
                    iconPath = getSmallAttribIconPath(FieldsM.query(payAttrib, "icon"));
                else
                    iconPath = getSmallAttribIconPath(FieldsM.query(payAttrib, "icon"));
                end

                moneyImg:setScale(1);
                enough = ME.user:queryAttrib(payAttrib) >= goodsPrice;
            end

            moneyImg:loadTexture(iconPath);
            TextStyleM.setTextStyle(moneyLabel, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_WHITE, true);
            moneyLabel:setString(tostring(goodsPrice));
            moneyLabel:getVirtualRenderer():setAdditionalKerning(getLocKerning() -3);
            if not enough then
                moneyLabel:setTextColor(TextStyleM.TEXT_COLOR_LIGHT_RED);
            else
                moneyLabel:setTextColor(TextStyleM.TEXT_COLOR_WHITE);
            end

            -- 居中显示
            local moneyImgW = moneyImg:getContentSize().width * moneyImg:getScaleX();
            local moneyLabelW = moneyLabel:getContentSize().width;
            -- 间隔
            local gap = 5;
            local s = (moneyImgW + moneyLabelW + gap) / 2;
            -- 位置调整
            moneyImg:setPositionX(-s - 3);
            moneyLabel:setPositionX(moneyImg:getPositionX() + moneyImgW + gap);

            -- 如果商品已售完，显示图标
            if soldOut then
                -- 背景变灰
                setGrayTransMode(goodsBg, true);
                setGrayTransMode(iconImg, true);

                -- 不显示图标、价格、星星
                moneyImg:setVisible(false);
                moneyLabel:setVisible(false);
                rankNode:setVisible(false);

                -- 显示已出售字样
                soldOutLabel:setVisible(true);
                TextStyleM.setTextStyle(soldOutLabel, TextStyleM.TEXT_SIZE_SMALL, TextStyleM.TEXT_COLOR_ORANGE, true);
                soldOutLabel:getVirtualRenderer():setAdditionalKerning(getLocKerning() -3);

                local soldOutText = DungeonShopM.queryShopRule(self.shopType, "sold_out_tip");
                if type(soldOutText) ~= "string" or soldOutText == "" then
                    soldOutText = getLocStr("has_been_sold");
                end
                soldOutLabel:setString(soldOutText);
            else
                -- 背景变亮
                setGrayTransMode(goodsBg, false);
                setGrayTransMode(iconImg, false);

                -- 显示图标、价格、星星
                moneyImg:setVisible(true);
                moneyLabel:setVisible(true);
                rankNode:setVisible(true);

                soldOutLabel:setVisible(false);
            end
        else
            -- 清空多余的格子
            grid:setVisible(false);
        end
    end
end

-- 获取可购买的商品信息
function UIDungeonShop:gatherGoodsInfo()
    -- 获取本店的所有商品
    local goodsList = DungeonShopM.getSellGoodsByType(self.shopType .. self.pos);
    if goodsList == nil then
        return nil;
    end

    local ret = {};
    local goodsIndex = 1;  -- 商品的序号
    for _, info in pairs(goodsList) do
        local goodsId    = info.goodsId;
        local soldOut    = iif(info["soldOut"], info["soldOut"], false);
        local arr        = DungeonShopM.queryPrice(goodsId);
        local payAttrib  = arr[2];           -- 支付属性
        local goodsPrice = arr[3];           -- 商品价格
        local itemInfo   = DungeonShopM.queryGoods(goodsId);
        local classId    = itemInfo[2];
        local goodsCount = itemInfo[3];      -- 商品数量
        local itemInfo   = ItemM.query(classId);
        if itemInfo then
            table.insert(ret, {goodsIndex, goodsId, itemInfo["icon"], payAttrib, goodsPrice, goodsCount,
                itemInfo["name"], itemInfo["desc"], soldOut, itemInfo["rank"]});
        end

        goodsIndex = goodsIndex + 1;
    end

    return ret;
end

-- 注册商品点击事件
function UIDungeonShop:registerItemTouchEvent(node)
    -- 注册商品图标点击事件
    local image = node:getChildByName("bg");
    local iconImage = node:getChildByName("goods_icon");
    local function onClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            AudioM.playFx("button_click");
            -- 仅处理非空的格子
            if type(iconImage.goodsIcon) == 'number' then
                onGoodsClick(self, iconImage);
            end
        end
    end
    image:addTouchEventListener(onClick);
    iconImage:addTouchEventListener(onClick);
end

-- 注册事件处理回调函数
function UIDungeonShop:registerEventCallback()
    -- 关注购买商品的事件
    EventMgr.register("UIDungeonShop", event.BUY_DUNGEON_GOODS, function(args)
        local goodsId  = args.goodsId;
        local shopType = args.shopType;
        local arr   = DungeonShopM.queryGoods(goodsId);
        local count = arr[3];
        local name  = ItemM.query(arr[2], "name");

        local classId = args.classId;
        if classId then
            name = ItemM.query(classId, "name") or name;
        end

        if string.startWith(shopType, "showcase") then
            -- 德古拉的展柜
            -- 提示解锁
            alert(string.format(getLocStr("unlock_holy_items"), name));
        else
            -- 提示玩家购买了商品
            alert(string.format(getLocStr("buy_goods_done"), name, count));
        end

        -- 刷新界面
        self:redraw();
    end)

    -- 注册获得焦点的回调
    EventMgr.register("UIDungeonShop", event.FOCUS_CHANGED, function(para)
        if para["get"] == "UIDungeonShop" then
            local dbase = DungeonShopM.queryShopRule(self.shopType, "dbase");
            if dbase.brave_vs_dragon == 1 then
                -- 勇者斗恶龙副本的商店
                UIMgr:getCurrentScene().topMenu:show(TOPMENU_FRAME_LADADUOMU_COIN, TOPMENU_FRAME_GEM);
            elseif self.shopType == "depot" then
                -- 补给站使用货币为“折弯的铜币”
                UIMgr:getCurrentScene().topMenu:show(TOPMENU_FRAME_COPPER, TOPMENU_FRAME_GEM);
            elseif self.shopType == "machine_institure" then
                -- 机械研究所"齿轮"
                UIMgr:getCurrentScene().topMenu:show(TOPMENU_FRAME_GEAR, TOPMENU_FRAME_GEM);
            else
                -- 其他使用探索点为货币
                UIMgr:getCurrentScene().topMenu:show(TOPMENU_FRAME_SP, TOPMENU_FRAME_GEM);
            end

            UIMgr:getCurrentScene().topMenu:setLocalZOrder(UIMgr.TOP_MENU_ZORDER + 2);
        end
    end);

    local topMenu = UIMgr.getCurrentScene().topMenu;

    -- 界面析构后，需要清理下
    self:registerScriptHandler(function(eventType)
        if eventType == "exit" then
            cclog("UIDungeonShop界面析构清理");
            EventMgr.removeAll("UIDungeonShop");

            if UIDungeonMgr:getCurLevel() then
                UIDungeonMgr:getCurLevel():showMenu();
            end

            -- 还原TopMenu的ZOrder
            if topMenu then
                topMenu:setVisible(self.oldVisible);
                topMenu:setLocalZOrder(self.oldZOrder);
            end
        elseif eventType == "enter" then
            if not UIDungeonMgr:getCurLevel() then
                UIDungeonMgr:getCurLevel():hideMenu();
            end

            -- 临时调高TOP_MENU的ZOrder
            self.oldVisible = topMenu:isVisible();
            UIMgr.getCurrentScene().topMenu:setVisible(true);
            self.oldZOrder = topMenu:getLocalZOrder();
        end
    end);
end

-- 注册点击事件
function UIDungeonShop:registerTouchEvent()
    -- 注册返回按钮点击事件
    local btnBack = findChildByName(self.node, "BT/btn_back");
    local function onBackClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            -- 关闭当前界面
            AudioM.playFx("button_return");
            UIMgr.getCurrentScene():removeFormByName("UIDungeonShop");
        end
    end
    AddBackEventHandler(self, btnBack, onBackClick);
    TextStyleM.setTextStyle(btnBack, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    btnBack:setTitleText(getLocStr("btn_text_back"));
end

-- 当商品被点击
function onGoodsClick(self, iconImg)
    if iconImg.soldOut then
        local tip = DungeonShopM.queryShopRule(self.shopType, "sold_out_tip2");
        if type(tip) ~= "string" or tip == "" then
            tip = getLocStr("goods_sold_out");
        end
        alert(tip);
        return;
    end

    -- 显示商品详细信息
    local uiDungeonGoods;
    local goodsId = DungeonShopM.queryGoods(iconImg.goodsId)[2];
    if EquipM.isEquipment(goodsId) == true then
        uiDungeonGoods = UIDungeonGoodsEquip.create(self.pos, self.shopType, iconImg.goodsIndex, iconImg.goodsId);
    else
        uiDungeonGoods = UIDungeonGoods.create(self.pos, self.shopType, iconImg.goodsIndex, iconImg.goodsId);
    end
    UIMgr.getCurrentScene():addForm(uiDungeonGoods);
    AudioM.playFx("button_spell");
end
